﻿#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>

using namespace cv;
using namespace std;

class LineRegression {
public:
    LineRegression() {}

    // 添加数据点
    void addDataPoint(double x1, double x2, double y) {
        data.push_back(DataPoint{x1, x2, y});
    }

    // 计算回归系数
    void calculateCoefficients() {
        int n = data.size();
        Mat X(n, 3, CV_64F);
        Mat Y(n, 1, CV_64F);

        for (int i = 0; i < n; ++i) {
            X.at<double>(i, 0) = 1.0; // 截距项
            X.at<double>(i, 1) = data[i].x1;
            X.at<double>(i, 2) = data[i].x2;
            Y.at<double>(i, 0) = data[i].y;
        }

        solve(X, Y, coefficients, DECOMP_NORMAL);
    }

    // 预测
    double predict(double x1, double x2) {
        Mat new_x = (Mat_<double>(1, 3) << 1, x1, x2);
        return new_x.dot(coefficients);
    }

    // 输出回归系数
    void printCoefficients() {
        cout << "Coefficients: " << endl << coefficients << endl;
    }

private:
    struct DataPoint {
        double x1;
        double x2;
        double y;
    };

    vector<DataPoint> data;
    Mat coefficients;
};

int main() {
    LineRegression lr;

    // 添加示例数据点
    lr.addDataPoint(1.0, 2.0, 3.0);
    lr.addDataPoint(2.0, 3.0, 6.0);
    lr.addDataPoint(3.0, 4.0, 9.0);
    lr.addDataPoint(4.0, 5.0, 12.0);

    // 计算回归系数
    lr.calculateCoefficients();

    // 打印回归系数
    lr.printCoefficients();

    // 预测
    double x1 = 5.0;
    double x2 = 6.0;
    double prediction = lr.predict(x1, x2);

    cout << "Prediction for x1=" << x1 << ", x2=" << x2 << ": " << prediction << endl;

    return 0;
}
